package com.yl.immodule.v;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.android.arouter.launcher.ARouter;
import com.camera.base.v.BaseActivity;
import com.camera.routemodule.RouterPath;
import com.yl.immodule.APP;
import com.yl.immodule.R;
import com.yl.immodule.v.models.ChatMessageViewModel;
import com.yl.immodule.widget.ChatMessageViewAdapter;
import com.yl.immodule.widget.MediaPlayerFactory;
import com.yl.immodule.widget.VoiceDialog;
import com.hm.poc.chat.ChatMessageStatus;
import com.unionbroad.greendao.ChatMessage;
import com.hm.poc.log.ALog;
import com.hm.poc.media.MediaFileUtil;
import com.hm.poc.media.MediaRecordFunc;
import com.hm.poc.media.OnVolumeListener;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import com.yl.immodule.databinding.ActivityChatMessageLayoutBinding;
import dagger.hilt.android.AndroidEntryPoint;

@AndroidEntryPoint
public class ChatMessageActivity extends BaseActivity<ActivityChatMessageLayoutBinding, ChatMessageViewModel> {

    public static final String EXTRAS_CHAT_ID = "extras_chat_id";
    @NonNull
    @Override
    protected Class<ChatMessageViewModel> getViewModelClass() {
        return ChatMessageViewModel.class;
    }
    private long chatId;
    private ChatMessageViewAdapter adapter;
    private Handler handler = new Handler();
    private VoiceDialog voiceDialog;
    private boolean isCurVoiceBtn = true;
    private boolean isIMEShown;
    private GestureDetector gestureDetector;
    private Vibrator vibrator;
    @Override
    public int getLayoutId() {
        return R.layout.activity_chat_message_layout;
    }


    @Override
    public int getStatusBarColor() {
        return R.color.title_background_color;
    }


    @Override
    public void loadData() {

    }

    @Override
    public void initView() {
        getMBinding().setViewModel(getViewModel());
        vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        chatId = getIntent().getLongExtra(EXTRAS_CHAT_ID, -1);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        getMBinding().recyclerView.setLayoutManager(layoutManager);

        getMBinding().recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.top = 4;
                outRect.bottom = 4;
            }
        });

        initViewModel();
        
        adapter = new ChatMessageViewAdapter(this, getMBinding().recyclerView, getViewModel(), this);
        getMBinding().recyclerView.setAdapter(adapter);

        ALog.d("ChatMessageActivity", "Show Chat[" + chatId + "] message list");

        getViewModel().setChatId(chatId);

        initViewListeners();
        
        // 设置一个消息列表监听器，在列表改变时滚动到底部
        getViewModel().messageList.observe(this, messages -> {
            // 延迟执行，确保RecyclerView已经完成更新
            handler.post(() -> {
                if (messages != null && !messages.isEmpty()) {
                    getMBinding().recyclerView.scrollToPosition(messages.size() - 1);
                }
            });
        });
    }

    private void initViewModel() {
    }

    @Override
    protected void onStop() {
        super.onStop();
        MediaPlayerFactory.getInstance().release();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MediaRecordFunc.getInstance().destroy();
    }
    public static void show(Activity context, long chatId) {
        Intent intent = new Intent(context, ChatMessageActivity.class);
        intent.putExtra(EXTRAS_CHAT_ID, chatId);
        context.startActivity(intent);
    }
    private void initViewListeners() {
        getMBinding().inputCam.setOnClickListener(v -> browserImageFile());

        getMBinding().inputEt.setPadding(30, 0, 0, 0);
        getMBinding().inputEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                updateSendBtnStatus(TextUtils.isEmpty(getMBinding().inputEt.getText().toString()));
            }
        });

        getMBinding().root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                getMBinding().root.getWindowVisibleDisplayFrame(r);
                int minKeyboardHeight = 150;
                int statusBarHeight = getStatusHeight(ChatMessageActivity.this);
                int screenHeight = getMBinding().root.getRootView().getHeight();
                int height = screenHeight - (r.bottom - r.top);
                if (isIMEShown) {
                    if (height - statusBarHeight < minKeyboardHeight) {
                        isIMEShown = false;
                    }
                } else {
                    if (height - statusBarHeight > minKeyboardHeight) {
                        isIMEShown = true;
                        if (adapter.getItemCount() > 0) {
                            getMBinding().recyclerView.smoothScrollToPosition(adapter.getLastPosition());
                        }
                    }
                }
            }
        });

        adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @SuppressLint("NewApi")
            @Override
            public void onItemClick(final AdapterView<?> parent, final View view, int position, long id) {
                ChatMessage message = adapter.getDataByPosition(position);
                if (message == null) {
                    return;
                }
            }
        });

        adapter.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
                final ChatMessage message = adapter.getDataByPosition(position);
                if (message == null) {
                    return false;
                }

                AlertDialog.Builder ab = new AlertDialog.Builder(ChatMessageActivity.this);
                ab.setCancelable(true);
                ab.setTitle("消息操作");
                ab.setItems(new String[]{"删除消息"}, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case 0:
                                getViewModel().deleteMessage(message);
                                dialog.dismiss();
                                break;
                        }
                    }
                });
                ab.show();
                return false;
            }
        });

        gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if (e1 == null || e2 == null) {
                    return false;
                }
                if (Math.abs(e2.getY() - e1.getY()) > 100 && Math.abs(velocityY) > 100) {
                    if (isIMEShown) {
                        hideIME();
                    }
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }
        });

        getMBinding().recyclerView.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));

        // 添加RecyclerView滚动监听器，以便在加载更多消息后自动滚动到底部
        getMBinding().recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, 
                                      int oldLeft, int oldTop, int oldRight, int oldBottom) {
                if (bottom < oldBottom) {
                    getMBinding().recyclerView.postDelayed(() -> {
                        if (adapter.getItemCount() > 0) {
                            getMBinding().recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);
                        }
                    }, 100);
                }
            }
        });

        getMBinding().chatSendPanel.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isCurVoiceBtn) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            startVoiceRecord();
                            return true;
                        case MotionEvent.ACTION_MOVE:
                            if (event.getX() <= -50 || event.getY() <= -50 || (event.getX() <= -35 && event.getY() <= -35)) {
                                showVoiceRecordCancelStatus(true);
                            } else {
                                showVoiceRecordCancelStatus(false);
                            }
                            break;
                        case MotionEvent.ACTION_UP:
                            if (event.getX() <= -50 || event.getY() <= -50 || (event.getX() <= -35 && event.getY() <= -35)) {
                                cancelVoiceRecord();
                            } else {
                                finishVoiceRecord();
                            }
                            return true;
                    }
                }
                return false;
            }
        });

        adapter.setOnItemResendClickListener(new ChatMessageViewAdapter.OnItemResendClickListener() {
            @Override
            public void onItemResendClick(View item, int position) {
                ChatMessage message = adapter.getDataByPosition(position);
                if (message == null) {
                    return;
                }
                if (message.getSip_status() == ChatMessageStatus.Sip.FAILED) {
                    getViewModel().sendMessage(message);
                }
            }
        });

        findViewById(R.id.chat_send_panel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isCurVoiceBtn) {
                    String text = getMBinding().inputEt.getText().toString().trim();
                    if (!TextUtils.isEmpty(text)) {
                        getViewModel().sendTextMessage(text);
                        getMBinding().inputEt.setText("");
                    }
                }
            }
        });
    }

    public int getStatusHeight(Context context) {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object object = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = (Integer) field.get(object);
            return context.getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            return 0;
        }
    }

    public void browserImageFile() {
//        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//        intent.setType("image/*");
//        intent.addCategory(Intent.CATEGORY_OPENABLE);
//        startActivityForResult(intent, 10086);
        ARouter.getInstance().
                build(RouterPath.path.im_camera_activity).
                withTransition(com.camera.base.R.anim.slide_in_left, com.camera.base.R.anim.slide_out_right)
                .navigation(this, 10086);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            Log.d("ChatMessageActivity", "用户取消了图片选择");
            return;
        }
        Log.e("TAG", "onActivityResult: "+requestCode + (data != null)   + (data.getData() != null));
        if (requestCode == 10086 && data != null) {
            try {
                String mediaPath = data.getStringExtra(CameraIMActivity.RESULT_MEDIA_PATH);
                if (mediaPath != null){
                    MediaFileUtil.MediaFile.MediaFileType type = MediaFileUtil.MediaFile.getFileType(mediaPath);
                    if (type != null) {
                        if (MediaFileUtil.MediaFile.isVideoFileType(type.fileType)) {
                            getViewModel().sendVideoFileMessage(mediaPath);
                        }else if (MediaFileUtil.MediaFile.isImageFileType(type.fileType)) {
                            getViewModel().sendImageMessage(mediaPath);
                        }
                    }
                }else{
                    if (data.getData() != null){
                        String path = MediaFileUtil.getPath(this, data.getData());
                        Log.d("ChatMessageActivity", "已选择图片: " + path);

                        MediaFileUtil.MediaFile.MediaFileType type = MediaFileUtil.MediaFile.getFileType(path);
                        if (type != null && MediaFileUtil.MediaFile.isImageFileType(type.fileType)) {
                            getViewModel().sendImageMessage(path);
                        } else {
                            Toast.makeText(this, "demo只实现了图片...", Toast.LENGTH_SHORT).show();
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                Log.e("ChatMessageActivity", "处理选择的图片时出错: " + e.getMessage());
                Toast.makeText(this, "选择图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void startVoiceRecord() {
        MediaPlayerFactory.getInstance().release();

        aniSendRoundLayoutScaleBig(true);
        showVoiceDialog(true);
        MediaRecordFunc.getInstance().startRecordAndFile(onVolumeListener);

        long[] pattern = {0, 40};
        vibrator.vibrate(pattern, -1);
    }

    private void showVoiceRecordCancelStatus(boolean show) {
        if (voiceDialog != null) {
            if (show) {
                voiceDialog.showCancel();
            } else {
                voiceDialog.showVoiceing();
            }
        }
    }

    private void cancelVoiceRecord() {
        aniSendRoundLayoutScaleBig(false);
        String filePath = MediaRecordFunc.getInstance().stopRecordAndFile();
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        showVoiceDialog(false);
    }

    private void finishVoiceRecord() {
        aniSendRoundLayoutScaleBig(false);
        String filePath = MediaRecordFunc.getInstance().stopRecordAndFile();
        ALog.d("ChatMessageActivity", "finishVoiceRecord: " + filePath);
        long duration = MediaRecordFunc.getInstance().getRecordTime();
        if (duration < 1000) {
            Toast.makeText(this, "录音时间太短", Toast.LENGTH_SHORT).show();
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
        } else {
            File file = new File(filePath);
            if (!file.exists()) {
                Toast.makeText(this, "录音失败", Toast.LENGTH_SHORT).show();
            } else {
                getViewModel().sendAudioFileMessage(filePath, duration / 1000);
            }
        }
        showVoiceDialog(false);
    }

    private void hideIME() {
        if (isIMEShown) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getMBinding().root.getWindowToken(), 0);
        }
    }

    private OnVolumeListener onVolumeListener = new OnVolumeListener() {
        @Override
        public void onVolumeChanged(int volume) {
            if (voiceDialog != null) {
                voiceDialog.updateVoice(volume);
            }
        }
    };

    private void showVoiceDialog(boolean show) {
        if (show) {
            if (voiceDialog == null) {
                voiceDialog = new VoiceDialog(this);
            }
            voiceDialog.show();
        } else {
            if (voiceDialog != null) {
                voiceDialog.dismiss();
            }
        }
    }

    void updateSendBtnStatus(boolean isVoice) {
        if (isCurVoiceBtn && !isVoice) {
            isCurVoiceBtn = false;
            aniSwitchSendButtonIcon(R.drawable.ic_input_send);
        } else if (!isCurVoiceBtn && isVoice) {
            isCurVoiceBtn = true;
            aniSwitchSendButtonIcon(R.drawable.ic_input_voice);
        }
    }

    void aniSwitchSendButtonIcon(final int iconResId) {
        final ArrayList<Animator> animators = new ArrayList<Animator>(3);
        ObjectAnimator xOutScaleAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "scaleX", 1.0f, 2.0f);
        ObjectAnimator yOutScaleAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "scaleY", 1.0f, 2.0f);
        ObjectAnimator outAlphaAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "alpha", 1.0f, 0.0f);
        xOutScaleAnim.setDuration(100);
        yOutScaleAnim.setDuration(100);
        outAlphaAnim.setDuration(100);
        animators.add(xOutScaleAnim);
        animators.add(yOutScaleAnim);
        animators.add(outAlphaAnim);
        AnimatorSet aniSet = new AnimatorSet();
        aniSet.playTogether(animators);
        aniSet.start();

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                getMBinding().sendBt.setImageResource(iconResId);
                ObjectAnimator xInScaleAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "scaleX", 0.0f, 1.0f);
                ObjectAnimator yInScaleAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "scaleY", 0.0f, 1.0f);
                ObjectAnimator inAlphaAnim = ObjectAnimator.ofFloat(getMBinding().sendBt, "alpha", 0.0f, 1.0f);
                xInScaleAnim.setDuration(50);
                xInScaleAnim.setDuration(50);
                xInScaleAnim.setDuration(50);
                animators.clear();
                animators.add(xInScaleAnim);
                animators.add(yInScaleAnim);
                animators.add(inAlphaAnim);
                AnimatorSet aniSet = new AnimatorSet();
                aniSet.playTogether(animators);
                aniSet.start();
            }
        }, 100);
    }

    void aniSendRoundLayoutScaleBig(boolean big) {
        final ArrayList<Animator> animators = new ArrayList<Animator>(2);
        ObjectAnimator xScaleAnim;
        ObjectAnimator yScaleAnim;
        if (big) {
            xScaleAnim = ObjectAnimator.ofFloat(getMBinding().chatSendPanel, "scaleX", getMBinding().chatSendPanel.getScaleX(), 2.1f);
            yScaleAnim = ObjectAnimator.ofFloat(getMBinding().chatSendPanel, "scaleY", getMBinding().chatSendPanel.getScaleY(), 2.1f);
        } else {
            xScaleAnim = ObjectAnimator.ofFloat(getMBinding().chatSendPanel, "scaleX", getMBinding().chatSendPanel.getScaleX(), 1.0f);
            yScaleAnim = ObjectAnimator.ofFloat(getMBinding().chatSendPanel, "scaleY", getMBinding().chatSendPanel.getScaleY(), 1.0f);
        }
        xScaleAnim.setDuration(350);
        yScaleAnim.setDuration(350);
        xScaleAnim.setInterpolator(new OvershootInterpolator(3.0F));
        yScaleAnim.setInterpolator(new OvershootInterpolator(3.0F));
        animators.add(xScaleAnim);
        animators.add(yScaleAnim);
        AnimatorSet aniSet = new AnimatorSet();
        aniSet.playTogether(animators);
        aniSet.start();
    }


}